8387488: [lworld] C2: acmp expansion fails with assert(replace != nullptr) failed: must succeed#2602
8387488: [lworld] C2: acmp expansion fails with assert(replace != nullptr) failed: must succeed#2602TobiHartmann wants to merge 5 commits into
Conversation
|
👋 Welcome back thartmann! A progress list of the required criteria for merging this PR into |
|
@TobiHartmann This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 4 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
| return v; | ||
| } | ||
|
|
||
| // TODO 8376254: C1 bails out if the type of the nullable flat field is uninitialized |
There was a problem hiding this comment.
Just found this missing TODO when browsing code.
Webrevs
|
| if (!not_vk->is_top()) { | ||
| region->add_req(not_vk); | ||
| result->add_req(igvn.intcon(0)); | ||
| if (cur_lhs_inline != nullptr && cur_lhs_inline->inline_klass() == vk) { |
There was a problem hiding this comment.
You can add a comment that it is not an issue if cur_lhs_inline is nullable and cur_lhs_field is null-checked, it is null-checked so that we can load the fields, and an InlineTypeNode does that already.
There was a problem hiding this comment.
It's not quite what I want to say. The null check is still present, the thing is that we ignored the null-checked value (the CastPP) and just use the raw value. This is because normally, we need a non-null CastPP to load from the object. That is unnecessary for an InlineTypeNode because we don't perform the loads.
There was a problem hiding this comment.
Okay, here's a new attempt 🙂
| } | ||
|
|
||
| // TODO 8376254: C1 bails out if the type of the nullable flat field is uninitialized | ||
| static ObjectHolderHolder tmp = new ObjectHolderHolder(); |
There was a problem hiding this comment.
It would probably be better to name this more specific to its type name so as not to have name collision.
marc-chevalier
left a comment
There was a problem hiding this comment.
Haven't found anything crazy, but with low confidence. Happy @merykitty was faster than me at reviewing this.
|
Thanks for the reviews Quan Anh and Marc! @merykitty I added a comment and adjusted the field name in the test. Please let me know what you think. |
merykitty
left a comment
There was a problem hiding this comment.
Thanks a lot, it looks good to me.
|
Thanks for the review Quan Anh! |
|
/integrate |
|
Going to push as commit 43153f5.
Your commit was automatically rebased without conflicts. |
|
@TobiHartmann Pushed as commit 43153f5. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
When slightly modifying the test that I added for JDK-8386067, I hit an assert in
CallStaticJavaNode::replace_is_substitutablebecause expansion of the substitutability call failed andemit_substitutability_checkreturnednullptralthoughcan_emit_substitutability_checkreturnedtrue.In the new test, the problematic field is
ObjectHolder::objwhich, although it is of typeObject, is alwaysexactand therefore can't be a value object and does not require a substitutability test.InlineTypeNode::can_emit_substitutability_checkcorrectly returnstrue:valhalla/src/hotspot/share/opto/inlinetypenode.cpp
Lines 611 to 614 in 2ae8e47
However, during recursive expansion, nullable value object fields are null-checked and then compared field-by-field:
valhalla/src/hotspot/share/opto/inlinetypenode.cpp
Line 910 in 2ae8e47
The code unconditionally rebuilt those fields with
InlineTypeNode::make_from_oopafter the null and type checks because there's aCastPPin-between:valhalla/src/hotspot/share/opto/inlinetypenode.cpp
Lines 955 to 960 in 2ae8e47
If the field was already scalarized, this discarded the existing
InlineTypeNodeand reloaded fields from the oop, losing precise information such as exact Object field Phis. The later Object field comparison then looks non-exact andemit_substitutability_check_pointerreturnsnullptr:valhalla/src/hotspot/share/opto/inlinetypenode.cpp
Lines 722 to 724 in 2ae8e47
The fix is to preserve already-scalarized recursive field operands when their inline klass matches the comparison klass, and only checkcast/reload operands that are not scalarized. With the fix, exact type information is preserved and we emit a pointer comparison for the exact object fields:
valhalla/src/hotspot/share/opto/inlinetypenode.cpp
Lines 700 to 702 in 2ae8e47
The IR Framework test verifies this successful expansion.
Note: The null and type checks are not immediately folded because by GVN because we need to set
set_delay_transformhere:valhalla/src/hotspot/share/opto/callnode.cpp
Lines 1412 to 1416 in 2ae8e47
Thanks,
Tobias
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/valhalla.git pull/2602/head:pull/2602$ git checkout pull/2602Update a local copy of the PR:
$ git checkout pull/2602$ git pull https://git.openjdk.org/valhalla.git pull/2602/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 2602View PR using the GUI difftool:
$ git pr show -t 2602Using diff file
Download this PR as a diff file:
https://git.openjdk.org/valhalla/pull/2602.diff
Using Webrev
Link to Webrev Comment